package 线程池.动态线程池;

import cn.hutool.core.thread.NamedThreadFactory;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.val;

import java.util.concurrent.*;

/**
 * 参考文章
 * 
 * @author caihe
 * @date 2022/7/19 15:07
 */
public class ThreadChangeDemo {

    private static final Log log = LogFactory.get();

    public static void main(String[] args) {
        try {
            dynamicModifyExecutor();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    
    
    private static ThreadPoolExecutor buildThreadPool() {
        ThreadFactory threadFactory = new ThreadFactoryBuilder()
                .setNameFormat("异步线程池中的线程" + "-%d")
                .setDaemon(true).build();
//        NamedThreadFactory namedThreadFactory = new NamedThreadFactory("caihe-ThreadPool", true);
        return new ThreadPoolExecutor(2, 5, 60, 
                TimeUnit.SECONDS,
                new ResizableCapacityLinkedBlockIngQueue<>(10),
                threadFactory);
    }
    
    
    private static void dynamicModifyExecutor() throws InterruptedException {
        ThreadPoolExecutor executor = buildThreadPool();
        for (int i = 0; i < 15; i++) {
            int finalI = i;
            executor.submit(() -> {
                threadPoolStatus(executor, "创建任务");
                log.info("执行第{}个任务中", finalI);
                try {
                    TimeUnit.SECONDS.sleep(5);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        threadPoolStatus(executor, "改变之前");
//        executor.setCorePoolSize(10);
//        executor.setMaximumPoolSize(100);
        ResizableCapacityLinkedBlockIngQueue queue = (ResizableCapacityLinkedBlockIngQueue) executor.getQueue();
        // 如果改变的的值小于原来 需要等待执行完成后再设置成功
        queue.setCapacity(2);

        threadPoolStatus(executor, "改变之后");


        for (int i = 0; i < 10; i++) {
            int finalI = i;

            executor.submit(() -> {
                threadPoolStatus(executor, "创建任务-新");
                log.info("执行第{}个新的任务中", finalI);
                try {
                    TimeUnit.SECONDS.sleep(5);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
        Thread.currentThread().join();
    }
    
    private static void threadPoolStatus(ThreadPoolExecutor executor, String name) {
        ResizableCapacityLinkedBlockIngQueue queue = (ResizableCapacityLinkedBlockIngQueue)executor.getQueue();

        System.out.println(Thread.currentThread().getName() + "-" + name + ":" + 
                "核心线程数：" + executor.getCorePoolSize() + 
                "最大线程数：" + executor.getMaximumPoolSize() + 
                " 活动线程数：" + executor.getActiveCount() + 
                " 任务完成数：" + executor.getCompletedTaskCount() +
                " queue.size：" + queue.size() + 
                " 队列大小：" + (queue.size() + queue.remainingCapacity()) + 
                " 当前队列剩余容量：" + queue.remainingCapacity() +
                " capacity：" + queue.getCapacity()
                );
    }
    
    
}
